package com.dingding.study.service.自定义注解操作数据库;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dingding.study.entity.Domain;
import com.dingding.study.mapper.DomainMapper;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author liugongding
 * @description:
 * @date 2023/5/9 5:59 PM
 */
@Slf4j
@Component
public class CacheLoadingUtil {

    @Autowired
    private DomainMapper domainMapper;

    public Cache<String, String> cache;

    {
         initCache();
    }

    public void initCache() {
        cache = CacheBuilder.newBuilder()
                .maximumSize(2)//最大个数(LRU+FIFO)
                .recordStats()//统计命中率
                .removalListener(removalNotification -> {
                    log.info("key：{}被移除，原因：{}", removalNotification.getKey(), removalNotification.getCause());
                })//移除通知
                //.build(new CacheLoader<String, Object>() {
                //    @Override //未命中读库
                //    public Object load(String key) {
                //        log.info("key:{}",key);
                //        return null;
                //    }
                //});
                .build();
    }

    public void loadingData(List<Domain> list) {
        //连接数据源   如果缓存没有则读取数据源
        if (CollectionUtils.isNotEmpty(list)) {
            Map<String, String> collect = list.stream().collect(
                        Collectors.toMap(x -> DigestUtils.md5DigestAsHex(x.getDataKey().getBytes()), Domain::getDataValue)
            );
            cache.putAll(collect);
        }
    }

    public String get(String key) throws Exception {
        String str = DigestUtils.md5DigestAsHex(key.getBytes());
        //回调方法用于读源并写入缓存
        String data = cache.getIfPresent(str);
        if (StringUtils.isEmpty(data)) {
            try {
                data = cache.get(str, () -> {
                    Domain domain = domainMapper.selectOne(new QueryWrapper<Domain>().eq("data_key", key));
                    if (domain != null) {
                        return domain.getDataValue();
                    }
                    return null;
                });
            } catch (CacheLoader.InvalidCacheLoadException e) {
                log.info(e.getMessage());
                return null;
            }
        }
        return data;
    }

}
